home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / window / _leda_panel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  20.7 KB  |  891 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _leda_panel.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. // defines the LEDA_PANEL operations declared in <LEDA/leda_panel.h>
  17. // using the basic graphics routines from <LEDA/impl/x_basic.h>
  18.  
  19. #include <LEDA/leda_panel.h>
  20. #include <LEDA/impl/x_basic.h>
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <stdlib.h>
  26.  
  27. enum { Text_Item, 
  28.        String_Item, 
  29.        String_Menu_Item, 
  30.        Int_Item, 
  31.        Slider_Item, 
  32.        Float_Item, 
  33.        Button_Item, 
  34.        Choice_Item,
  35.        Bool_Item};
  36.  
  37. static char* duplicate_string(const char* p)
  38. { char* q = new char[strlen(p)+1];
  39.   if (q==0) 
  40.   { fprintf(stderr,"duplicate_string: out of memory");
  41.     abort();
  42.    }
  43.   strcpy(q,p);
  44.   return q;
  45. }
  46.  
  47.  
  48. void LEDA_PANEL::panel_redraw_func() 
  49. { LEDA_PANEL* p = (LEDA_PANEL*)active_window; 
  50.   p->open(p->XPOS, p->YPOS, 0, 0, 0, 0, 0); }
  51.  
  52.  
  53.  
  54. LEDA_PANEL::LEDA_PANEL(const char* s, int bl)
  55. { header = duplicate_string(s);
  56.   but_layout = bl;
  57.   item_count = 0;
  58.   but_count = 0;
  59.   XPOS = -1;
  60.   YPOS = -1;
  61.   win = 0;
  62.   redraw = panel_redraw_func;
  63.  }
  64.  
  65. void LEDA_PANEL::text_item(const char* s)
  66. { kind[item_count] = Text_Item;
  67.   label_str[item_count] = duplicate_string(s);
  68.   item_count++;
  69. }
  70.  
  71. void LEDA_PANEL::string_item(const char* s, char** x)
  72. { label_str[item_count] = duplicate_string(s);
  73.   ref[item_count] = x;
  74.   kind[item_count] = String_Item;
  75.   item_count++;
  76.  }
  77.  
  78. void  LEDA_PANEL::string_menu_item(const char* s, char** x, const char* /*menu_label*/,
  79.                                    int argc, const char** argv)
  80. { label_str[item_count] = duplicate_string(s);
  81.   ref[item_count] = x;
  82.   kind[item_count] = String_Menu_Item;
  83.   dat1[item_count] = argc;
  84.   choices[item_count] = new char*[argc];
  85.   for(int i = 0; i < argc; i++) 
  86.      choices[item_count][i] = duplicate_string(argv[i]);
  87.   item_count++;
  88.  }
  89.  
  90.  
  91. void LEDA_PANEL::int_item(const char* s, int* x)
  92. { label_str[item_count] = duplicate_string(s);
  93.   ref[item_count] = x;
  94.   kind[item_count] = Int_Item;
  95.   item_count++;
  96.  }
  97.  
  98. void  LEDA_PANEL::slider_item(const char* s, int* x, int min, int max)
  99. { label_str[item_count] = duplicate_string(s);
  100.   ref[item_count] = x;
  101.   dat1[item_count] = min;
  102.   dat2[item_count] = max;
  103.   kind[item_count] = Slider_Item;
  104.   item_count++;
  105.  }
  106.  
  107. void LEDA_PANEL::float_item(const char* s, double* x)
  108. { label_str[item_count] = duplicate_string(s);
  109.   ref[item_count] = x;
  110.   kind[item_count] = Float_Item;
  111.   item_count++;
  112.  }
  113.  
  114. void LEDA_PANEL::choice_item(const char* s, int* address, int argc,
  115.                              const char** argv, int step, int off)
  116. { label_str[item_count] = duplicate_string(s);
  117.   kind[item_count] = Choice_Item;
  118.   ref[item_count] = address;
  119.   dat1[item_count] = argc;
  120.   dat2[item_count] = step;
  121.   offset[item_count] = off;
  122.   choices[item_count] = new char*[argc];
  123.   for(int i=0; i<argc; i++) choices[item_count][i] = duplicate_string(argv[i]);
  124.   item_count++;
  125.  }
  126.  
  127.  
  128. void LEDA_PANEL::bool_item(const char* s, char* address)
  129. { label_str[item_count] = duplicate_string(s);
  130.   kind[item_count] = Bool_Item;
  131.   ref[item_count] = address;
  132.   dat1[item_count] = 2;
  133.   dat2[item_count] = 1;
  134.   offset[item_count] = 0;
  135.   choices[item_count] = new char*[2];
  136.   choices[item_count][0] = duplicate_string("off");
  137.   choices[item_count][1] = duplicate_string("on");
  138.   item_count++;
  139.  }
  140.  
  141.  
  142.  
  143. int LEDA_PANEL::button(const char* s)
  144. { if (but_count == MAX_BUT_NUM) return -1;
  145.   // space before first line of buttons
  146.   if (but_count==0 && item_count>0)  text_item(""); 
  147.   button_str[but_count] = duplicate_string(s);
  148.   return but_count++;
  149.  }
  150.  
  151.  
  152. void  LEDA_PANEL::button_line(int n, const char** b) 
  153. { for(int i=0; i<n; i++) button(b[i]); }
  154.  
  155.  
  156.  
  157. void LEDA_PANEL::activate_string_item(int xoff,int yoff,int yskip,int ytskip, 
  158.                                       int t_length, int n)
  159. {  int y,l,i;
  160.  
  161.    int old = act_str_item;
  162.  
  163.    act_str_item = n;
  164.  
  165.    if (old > -1)
  166.    { y = yoff;
  167.      for(i=0;i<old; i++)
  168.         y += (kind[i] == Text_Item) ? ytskip : yskip; 
  169.      l = dat2[old];
  170.      ::set_mode(1);
  171.      line(win,xoff,y+yskip-3,xoff+t_length,y+yskip-3);
  172.      ::set_mode(0);
  173.      put_text(win,xoff+l*text_width("H"),y+(yskip-text_height("H"))/2," ",1);
  174.    }
  175.  
  176.    y = yoff;
  177.    for(i=0;i<n; i++)
  178.       y += (kind[i] == Text_Item) ? ytskip : yskip; 
  179.    l = dat2[n];
  180.    line(win,xoff,y+yskip-3,xoff+t_length,y+yskip-3);
  181.    put_text(win,xoff+l*text_width("H"),y+(yskip-text_height("H"))/2,"|",1);
  182.  
  183.  }
  184.    
  185.  
  186.  
  187. int LEDA_PANEL::panel_text_edit(int xt, int yt, int t_len, char *str)
  188. { int  i = strlen(str);
  189.   int  x;
  190.   int  cw;
  191.   int  xcoord,ycoord,val;
  192.   int  max_c;
  193.   unsigned long t;
  194.    
  195.   cw = text_width("H");
  196.   x  = xt+i*cw;
  197.  
  198.   max_c = t_len/cw;
  199.  
  200.   put_text(win,xt,yt,str,1);
  201.  
  202.   for(;;)
  203.   { int  k;
  204.     char c = 13;
  205.  
  206.     ::set_read_gc();
  207.  
  208.     while(1)
  209.     { Window w;
  210.       k = get_next_event(&w,&val,&xcoord,&ycoord,&t);
  211.       if (w != win) continue;
  212.       if (k == key_press_event || k == button_press_event) break;
  213.      }
  214.  
  215.      reset_gc();
  216.  
  217.      if (k == key_press_event) c = val;
  218.      if (c == 13) 
  219.      { put_back_event();
  220.        break;
  221.       }
  222.  
  223.      if (i < max_c && isprint(c))
  224.      { str[i]=c;
  225.        str[i+1]=0;
  226.        put_text(win,xt,yt,str,1);
  227.        i++;
  228.        x += cw;
  229.       }
  230.      if(c==8 && i>0)
  231.      { put_text(win,x,yt," ",1);
  232.        i--;
  233.        x -= cw;
  234.       }
  235.      put_text(win,x,yt,"|",1);
  236.    }
  237.  
  238.   str[i]='\0';
  239.  
  240.   ::set_text_font();
  241.  
  242.   return i;
  243. }
  244.  
  245.  
  246. void LEDA_PANEL::put_text_item(int x, int y, const char* s, int t_len)
  247. { char text[128];
  248.   int i;
  249.   int c_len = t_len/text_width("H");
  250.   strcpy(text,s);
  251.   for(i=strlen(s); i<c_len; i++) text[i] = ' ';
  252.   text[c_len] = '\0';
  253.   put_text(win,x,y,text,1);
  254. }
  255.  
  256.  
  257.  
  258. void LEDA_PANEL::draw_choice_item(int i,int x0, int y0, int width,int yskip)
  259. { int c = (*(int*)ref[i]-offset[i])/dat2[i];
  260.   int x = x0+c*width;
  261.   int j;
  262.  
  263.   for(j=0, x=x0; j < dat1[i]; j++, x+=width)
  264.   { ::set_color(0);
  265.     box(win,x+1,y0+4,x+width-1,y0+yskip-3);
  266.     ::set_color(1);
  267.     rectangle(win,x,y0+3,x+width,y0+yskip-2);
  268.     if(j == c) rectangle(win,x+1,y0+4,x+width-1,y0+yskip-3);
  269.     put_ctext(win,x+width/2,y0+yskip/2,choices[i][j],0);
  270.    }
  271. }
  272.  
  273.  
  274. void LEDA_PANEL::draw_bool_item(int i,int x0, int y0, int width,int yskip)
  275. { char c = *(char*)ref[i];
  276.   int x = x0+c*width;
  277.   int j;
  278.  
  279.   for(j=0, x=x0; j < 2; j++, x+=width)
  280.   { ::set_color(0);
  281.     box(win,x+1,y0+4,x+width-1,y0+yskip-3);
  282.     ::set_color(1);
  283.     rectangle(win,x,y0+3,x+width,y0+yskip-2);
  284.     if(j == c) rectangle(win,x+1,y0+4,x+width-1,y0+yskip-3);
  285.     put_ctext(win,x+width/2,y0+yskip/2,choices[i][j],0);
  286.    }
  287.  
  288. }
  289.  
  290.  
  291. void LEDA_PANEL::draw_slider_item(int i, int x01, int x0, int y0,
  292.                                   int length, int yskip, float x)
  293. { float mi = dat1[i];
  294.   float ma = dat2[i];
  295.   int x1 = x0 + length;
  296.   int y1 = y0 + (3*yskip)/4;
  297.   char text[16];
  298.  
  299.   y0 += (1+yskip/4);
  300.  
  301.   if (x < x0) x = x0;
  302.   if (x > x1) x = x1;
  303.  
  304.   int val = int(mi + (ma-mi)*(x-x0)/length + 0.5);
  305.   *(int*)ref[i] = val;
  306.  
  307.   sprintf(text,"%3d",val);
  308.   put_text(win,x01,y0,text,1);
  309.  
  310.   ::set_color(0);
  311.   box(win,int(x+0.5)+1,y0+1,x1-1,y1-1);
  312.   ::set_color(1);
  313.   box(win,x0,y0+1,int(x+0.5),y1-1);
  314.   rectangle(win,x0,y0,x1,y1);
  315.  
  316. }
  317.  
  318. void LEDA_PANEL::draw_button(const char* s, int x, int y, int bw, 
  319.                               int yskip, int pressed)
  320.   if (pressed)
  321.   { ::set_mode(1);
  322.     box(win,x+2,y+5,x+bw-2,y+yskip-4);
  323.     flush_display();
  324.     ::set_mode(0);
  325.    }
  326.   else
  327.   { ::set_color(0);
  328.     box(win,x+1,y+4,x+bw-1,y+yskip-3);
  329.     ::set_color(1);
  330.     if (s) 
  331.        put_ctext(win,x+bw/2,y+yskip/2,s,0);
  332.     else // menu button  "-->"
  333.       { line(win,x+9, y+8,  x+9,  y+20);
  334.         line(win,x+9, y+8,  x+21, y+14);
  335.         line(win,x+9, y+20, x+21, y+14);
  336.         line(win,x+10, y+9,  x+20, y+14);
  337.         line(win,x+10, y+19, x+20, y+14);
  338.        }
  339.     rectangle(win,x+1,y+4,x+bw-1,y+yskip-3);
  340.  
  341.     // shadow
  342.     box(win,x+4,y+yskip-2,x+bw,y+yskip);
  343.     box(win,x+bw,y+7,x+bw+2,y+yskip);
  344.  
  345.    }
  346.  
  347.   
  348.  }
  349.  
  350.  
  351. static int read_panel_at(const char* header, int n, char** but,int x, int y)
  352. { LEDA_PANEL p(header);
  353.   for(int i=0; i<n; i++) p.button(but[i]);
  354.   return p.open(x,y,0,0,0,0,3);
  355.  }
  356.  
  357.  
  358. int  LEDA_PANEL::open(int xpos, int ypos, int win_x, int win_y, 
  359.                       int win_width, int win_height, int mode)
  360. {
  361.  
  362.  
  363.   // mode = 0:  just display panel window  on screen
  364.   // mode = 1:  display, read (blocking), and close 
  365.   // mode = 2:  read
  366.   // mode = 3:  display, read (non-blocking) , and close
  367.  
  368.  
  369.   char  text[128];
  370.   char  str[128];
  371.  
  372.  
  373. repaint:
  374.  
  375.   int   width = (win) ? ::window_width(win) : 100;
  376.   int   height; 
  377.  
  378.  
  379.   int   xoff  = 20;       /* left and right boundary space */
  380.   int   yoff  = 10;       /* top and bottom boundary space */
  381.   int   xoff1 =  0;       /* start of slider items    */
  382.   int   xoff2 =  0;       /* start of all other items */
  383.  
  384.   int   bxoff;            /* left and right button boundary space */
  385.  
  386.   int   sl_length = 200;  /* slider item length */
  387.   int   t_length  = 200;  /* string/int/float item length */
  388.  
  389.   int   ytskip = 18;      /* height of text items   */
  390.   int   yskip  = 28;      /* height of other items  */
  391.  
  392.   int   bw     = 50;      /* button width (minimal) */
  393.   int   bskip  = 15;      /* button space */
  394.   int   bw1;              /* bw + bskip   */
  395.  
  396.   int   cw     = 30;      /* choice field width (minimal) */
  397.  
  398.  
  399.   int   but_per_line;
  400.   int   but_lines;
  401.  
  402.  
  403.   int   but,w,i,j,x,y,yt;
  404.  
  405.   int   save_lw, save_ls, save_mo;
  406.  
  407.   int   user_buttons = but_count;
  408.  
  409.   unsigned long t;
  410.  
  411.   open_display();
  412.  
  413.   save_lw = ::set_line_width(1);
  414.   save_ls = ::set_line_style(0);
  415.   save_mo = ::set_mode(0);
  416.  
  417.   if (but_count==0)
  418.   { button("CONTINUE");
  419.     button("QUIT");
  420.    }
  421.  
  422.  
  423.   height = 2*yoff;
  424.  
  425.   for(i=0;i<item_count; i++)
  426.     if (kind[i] != Text_Item)
  427.        { height += yskip;
  428.          if ((w = text_width(label_str[i])) > xoff1) xoff1 = w;
  429.  
  430.          if (kind[i] == Choice_Item)
  431.          { int j;
  432.            for(j=0; j<dat1[i];j++)
  433.            if ((w = text_width(choices[i][j])) > cw) cw = w;
  434.           }
  435.        }
  436.     else
  437.        height += ytskip;
  438.  
  439.   cw    += 10;
  440.  
  441.   xoff1 += 25;
  442.  
  443.   xoff2 = xoff1 + 35;
  444.  
  445.  
  446.   if ((w = text_width(header)) > width) width = w;
  447.  
  448.   for(i=0;i<item_count; i++)
  449.   { switch (kind[i])
  450.     {
  451.       case  Text_Item:
  452.                   if ((w = 2*xoff + text_width(label_str[i])) > width) width=w;
  453.                   if ((w = text_width(label_str[i])-xoff2) > sl_length)
  454.                      sl_length = w;
  455.                   if (w > t_length) t_length = w;
  456.                   break;
  457.  
  458.  
  459.       case Choice_Item:
  460.                  if ((w = xoff2 + cw*dat1[i] + xoff) > width) width = w;
  461.                  break;
  462.  
  463.       case Slider_Item:
  464.                  if ((w = xoff2+sl_length+xoff) > width) width = w;
  465.                  break;
  466.  
  467.       case String_Menu_Item:
  468.                  if ((w = xoff2+t_length+2*yskip+xoff) > width) width = w;
  469.                  break;
  470.  
  471.       default:   if ((w = xoff2+t_length+xoff) > width) width = w;
  472.                  break;
  473.      }
  474.    }
  475.  
  476.  
  477.   for(i=0; i < but_count; i++)
  478.      if ((w = text_width(button_str[i])) > bw) bw = w;
  479.  
  480.   bw  = bw += 10;
  481.   bw1 = bw + bskip;
  482.  
  483.   if (width < bw1+bskip) width = bw1+bskip;
  484.  
  485.   if (but_layout == 0)
  486.      but_per_line = (width-bskip)/bw1;
  487.   else
  488.      but_per_line = 1;
  489.  
  490.   but_lines = but_count/but_per_line;
  491.  
  492.   if (but_count % but_per_line) but_lines++;
  493.  
  494.   if (but_lines == 1)
  495.      bxoff = (width - but_count * bw1 + bskip)/2;
  496.   else
  497.      bxoff = (width - but_per_line * bw1 + bskip)/2;
  498.  
  499.   height += but_lines * yskip;
  500.  
  501.   for (i=0; i< but_lines; i++)
  502.      kind[item_count+i] = Button_Item;
  503.  
  504.  
  505.   if(XPOS == -1)
  506.     if (xpos == -1)
  507.       if (win_width == 0)
  508.          { /* center panel window on the screen */
  509.            XPOS = (display_width() - width)/2;
  510.            YPOS = (display_height() - height)/2;
  511.           }
  512.       else
  513.          { /* center panel window on draw window */
  514.            XPOS = win_x + (win_width - width)/2;
  515.            YPOS = win_y + (win_height- height)/2;
  516.           }
  517.     else /* use supplied coordinates */
  518.       { XPOS = xpos;
  519.         YPOS = ypos;
  520.        }
  521.  
  522.   //if (win==0) win = open_window(XPOS,YPOS,width,height,header,"LEDA PANEL");
  523.  
  524.   if (win==0) 
  525.   { LEDA_WINDOW::open(width,height,XPOS,YPOS,header);
  526.     set_show_coordinates(0);
  527.     redraw = panel_redraw_func;
  528.     win = draw_win;
  529.    }
  530.  
  531.  
  532. //repaint:
  533.  
  534.   //clear_window(win,orange);
  535.  
  536.   act_str_item = -1;
  537.  
  538.   ::set_color(1);
  539.  
  540.   y = yoff;
  541.  
  542.   for(i=0;i<item_count; i++)
  543.   {
  544.     yt = y + (yskip - text_height("H"))/2;
  545.  
  546.     if (kind[i] != Text_Item) put_text(win,xoff,yt,label_str[i],0);
  547.  
  548.     switch (kind[i]) {
  549.  
  550.     case Text_Item:
  551.         { put_text(win,xoff,y,label_str[i],0);
  552.           break;
  553.          }
  554.  
  555.  
  556.     case Choice_Item:
  557.         { draw_choice_item(i,xoff2,y,cw,yskip);
  558.           break;
  559.          }
  560.  
  561.     case Bool_Item:
  562.         { draw_bool_item(i,xoff2,y,cw,yskip);
  563.           break;
  564.          }
  565.  
  566.     case Slider_Item:
  567.         { float d = float(sl_length)/(dat2[i]-dat1[i]);
  568.           float x = xoff2 + d * (*(int*)ref[i]-dat1[i]);
  569.           draw_slider_item(i,xoff1,xoff2,y,sl_length,yskip,x);
  570.           break;
  571.          }
  572.  
  573.     case Int_Item:
  574.         { sprintf(text,"%d",*(int*)ref[i]);
  575.           put_text(win,xoff2,yt,text,1);
  576.           dat2[i] = strlen(text);
  577.           line(win,xoff2,y+yskip-4,xoff2+t_length,y+yskip-4);
  578.           if (act_str_item == -1) 
  579.               activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  580.           break;
  581.          }
  582.  
  583.     case Float_Item:
  584.         { sprintf(text,"%f",*(double*)ref[i]);
  585.           put_text(win,xoff2,yt,text,1);
  586.           dat2[i] = strlen(text);
  587.           line(win,xoff2,y+yskip-4,xoff2+t_length,y+yskip-4);
  588.           if (act_str_item == -1) 
  589.               activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  590.           break;
  591.          }
  592.   
  593.     case String_Item:
  594.         { put_text(win,xoff2,yt,*(char**)ref[i],1);
  595.           dat2[i] = strlen(*(char**)ref[i]);
  596.           line(win,xoff2,y+yskip-4,xoff2+t_length,y+yskip-4);
  597.           if (act_str_item == -1) 
  598.               activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  599.           break;
  600.          }
  601.  
  602.     case String_Menu_Item:
  603.         { put_text(win,xoff2,yt,*(char**)ref[i],1);
  604.           dat2[i] = strlen(*(char**)ref[i]);
  605.           line(win,xoff2,y+yskip-4,xoff2+t_length,y+yskip-4);
  606.           draw_button(0,xoff2+t_length+10,y-1,yskip,yskip-1,0);
  607.           if (act_str_item == -1) 
  608.               activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  609.           break;
  610.          }
  611.     
  612.     
  613.     }
  614.  
  615.     if (kind[i] == Text_Item)
  616.         y += ytskip;
  617.     else
  618.         y += yskip;
  619.  
  620.   }
  621.  
  622.   y -= yskip;
  623.  
  624.   for(i=0; i < but_count; i++)
  625.     { if (i % but_per_line == 0)
  626.       { y += yskip;
  627.         x = bxoff;
  628.        }
  629.       draw_button(button_str[i],x,y,bw,yskip,0);
  630.       x += bw1;
  631.      }
  632.  
  633.  
  634.   if (mode == 0) return -1;
  635.  
  636.  
  637.  
  638.  
  639.   but = -1;
  640.  
  641.   while(but == -1)
  642.   { int b;
  643.     i = -1;
  644.  
  645.  
  646.     while (i < 0 || i >= item_count+but_lines)
  647.     { int k;
  648.       ::set_read_gc();
  649.       while (1)
  650.       { Window w;
  651.         k = get_next_event(&w,&b,&x,&y,&t);
  652.         if (w == win)
  653.         { if (k == button_press_event || k == key_press_event) break;
  654.           if (k == configure_event) 
  655.           { reset_gc();
  656.             goto repaint;
  657.            }
  658.          }
  659.         else
  660.           if (mode == 3 && k==button_press_event) 
  661.           { put_back_event();
  662.             reset_gc();
  663.             goto end;
  664.            }
  665.        }
  666.       reset_gc();
  667.  
  668.       if (k==button_press_event)
  669.         { for(i=0,j=yoff;i<item_count+but_lines && y>j; i++)
  670.             if (kind[i] == Text_Item)
  671.                j += ytskip;
  672.             else
  673.                j += yskip;
  674.   
  675.            if (y <= j) i--;
  676.          }
  677.        else  /* key pressed */
  678.        { if (b == 13 && act_str_item > -1) /* return */
  679.          { j = act_str_item;
  680.            for(;;)
  681.            { j = (j + 1) % item_count;
  682.              k =  kind[j]; 
  683.              if (k==String_Item || k==String_Menu_Item || 
  684.                  k==Int_Item || k == Float_Item) break;
  685.              }
  686.            activate_string_item(xoff2,yoff,yskip,ytskip,t_length,j);
  687.          }
  688.          else
  689.          { x = xoff2;
  690.            i = act_str_item;
  691.            for(k=0,j=yoff; k <= i; k++)
  692.             if (kind[k] == Text_Item)
  693.                j += ytskip;
  694.             else
  695.                j += yskip;
  696.            put_back_event();
  697.           }
  698.        }
  699.      }
  700.  
  701.     y  = j-yskip;
  702.     yt = y + (yskip - text_height("H"))/2;
  703.  
  704.     switch (kind[i]) {
  705.  
  706.     case Text_Item: break;
  707.  
  708.     case Slider_Item:
  709.     { Window w = win;
  710.       int xx = 0;
  711.       if (x < xoff2 || x > xoff2+sl_length) break;
  712.       ::set_read_gc();
  713.       while(w == win)
  714.       { if (xx != x)
  715.         { xx = x;
  716.           reset_gc();
  717.           draw_slider_item(i,xoff1,xoff2,y,sl_length,yskip,xx);
  718.           ::set_read_gc();
  719.          }
  720.         if (get_next_event(&w,&b,&x,&j,&t) == button_release_event) break;
  721.        }
  722.       reset_gc();
  723.       break;
  724.      }
  725.  
  726.     case Int_Item:
  727.     { int* ptr = (int*)ref[i];
  728.       sprintf(str,"%d",*ptr);
  729.       activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  730.       panel_text_edit(xoff2,yt,t_length,str);
  731.       *ptr = atoi(str);
  732.       sprintf(str,"%d",*ptr);
  733.       dat2[i] = strlen(str);
  734.       sprintf(text,"%s|                    ",str);
  735.       put_text_item(xoff2,yt,text,t_length);
  736.       break;
  737.      }
  738.  
  739.     case Float_Item:
  740.     { double* ptr = (double*)ref[i];
  741.       sprintf(str,"%f",*ptr);
  742.       activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  743.       panel_text_edit(xoff2,yt,t_length,str);
  744.       *ptr = (double)atof(str);
  745.       sprintf(str,"%f",*ptr);
  746.       dat2[i] = strlen(str);
  747.       sprintf(text,"%s|                    ",str);
  748.       put_text_item(xoff2,yt,text,t_length);
  749.       break;
  750.      }
  751.  
  752.     case String_Item:
  753.     { strcpy(str,*(char**)ref[i]);
  754.       activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  755.       panel_text_edit(xoff2,yt,t_length,str);
  756.       delete *(char**)ref[i];
  757.       *(char**)ref[i] = duplicate_string(str);
  758.       dat2[i] = strlen(str);
  759.       put_text_item(xoff2,yt,str,t_length);
  760.       break;
  761.      }
  762.  
  763.     case String_Menu_Item:
  764.     { activate_string_item(xoff2,yoff,yskip,ytskip,t_length,i);
  765.       strcpy(str,*(char**)ref[i]);
  766.       if (x < xoff2+t_length+10)
  767.          { strcpy(str,*(char**)ref[i]);
  768.            panel_text_edit(xoff2,yt,t_length,str);
  769.           }
  770.       else
  771.          { Window w;
  772.            draw_button(0,xoff2+t_length+10,y-1,yskip,yskip-1,1);
  773.            while (get_next_event(&w,&b,&x,&j,&t) != button_release_event);
  774.            draw_button(0,xoff2+t_length+10,y-1,yskip,yskip-1,1);
  775.            int sel = read_panel_at(label_str[i],dat1[i],choices[i],
  776.                                    XPOS+xoff2+t_length+16, YPOS+y+24);
  777.            if (sel > -1) strcpy(str,(choices[i])[sel]);
  778.           }
  779.  
  780.       delete *(char**)ref[i];
  781.       *(char**)ref[i] = duplicate_string(str);
  782.       dat2[i] = strlen(str);
  783.       sprintf(text,"%s|                   ",str);
  784.       put_text_item(xoff2,yt,text,t_length);
  785.       break;
  786.      }
  787.  
  788.  
  789.    case Choice_Item:
  790.    { j = (x-xoff2)/cw;
  791.      if (j >= 0 && j<dat1[i])
  792.      { *(int*)ref[i] = offset[i] + j * dat2[i];
  793.        draw_choice_item(i,xoff2,y,cw,yskip);
  794.       }
  795.      break;
  796.     }
  797.  
  798.    case Bool_Item:
  799.    { j = (x-xoff2)/cw;
  800.      if (j >= 0 && j<dat1[i])
  801.      { *(char*)ref[i] = offset[i] + j * dat2[i];
  802.        draw_bool_item(i,xoff2,y,cw,yskip);
  803.       }
  804.      break;
  805.     }
  806.  
  807.    case Button_Item:
  808.    { j = (x-bxoff)/bw1;
  809.      i = (i-item_count)*but_per_line +j;
  810.      if (x > bxoff && j < but_per_line && i < but_count)
  811.      { Window w;
  812.        draw_button(button_str[i],bxoff+j*bw1,y,bw,yskip,1);
  813.        while (get_next_event(&w,&b,&b,&b,&t) != button_release_event);
  814.        but = i;
  815.        //if (mode == 2) draw_button(button_str[i],bxoff+j*bw1,y,bw,yskip,1);
  816.       }
  817.      break;
  818.     }
  819.  
  820.    }
  821.  
  822.   }
  823.  
  824.  
  825.  if (mode == 2) // redisplay
  826.      open(XPOS,YPOS,0,0,0,0,0);
  827.  
  828. /*
  829.   window_position(win,&(XPOS),&(YPOS));
  830. */
  831.  
  832. end:
  833.  
  834.  
  835.   ::set_line_width(save_lw);
  836.   ::set_line_style(save_ls);
  837.   ::set_mode(save_mo);
  838.  
  839.   if (user_buttons == 0)
  840.   { but_count = 0;
  841.     item_count--;
  842.     if (but == 1)   /* quit button pressed */
  843.     { close_display();
  844.       exit(0);
  845.      }
  846.    }
  847.  
  848.   if (mode != 2) close();
  849.  
  850.   return but;
  851. }
  852.  
  853.  
  854. void LEDA_PANEL::display(int xpos, int ypos, int win_x, int win_y, int win_width, int win_height)
  855. { open(xpos, ypos, win_x, win_y, win_width, win_height, 0); }
  856.  
  857. /*
  858. int  LEDA_PANEL::read(int xpos, int ypos, int win_x, int win_y, int win_width, int win_height)
  859. { return open(xpos, ypos, win_x, win_y, win_width, win_height, 2); }
  860. */
  861.  
  862. int  LEDA_PANEL::read() { return open(XPOS,YPOS,0,0,0,0,2); }
  863.  
  864.  
  865.  
  866. void  LEDA_PANEL::close() 
  867. { close_window(win);
  868.   win = 0;
  869.   draw_win = 0;
  870.  }
  871.  
  872.  
  873.  
  874. LEDA_PANEL::~LEDA_PANEL() 
  875. { delete header; 
  876.   for(int i = 0; i<item_count; i++)
  877.   { delete label_str[i];
  878.     if (   kind[i] == String_Menu_Item 
  879.         || kind[i] == Choice_Item 
  880.         || kind[i] == Bool_Item    )
  881.     { for(int j = 0; j < dat1[i]; j++) delete choices[i][j];
  882.       delete choices[i];
  883.      }
  884.    }
  885.   for(int j = 0; j<but_count; j++) delete button_str[j];
  886. }
  887.  
  888.  
  889.